﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Silvermoon.Controls;
using MAPIdotnet;
using OutlookHub.Models;
using OutlookHub.Utils;
using Silvermoon.OpenGL;
using Silvermoon.Windows;
using System.Globalization;
using System.Drawing;
using Silvermoon.UI;
using OutlookHub.Controllers;
using Silvermoon.Shapes;
using Silvermoon;

namespace OutlookHub.Controls
{
    public class EMailItem : ContainerItem
    {
        const int infoWidth = 94;
        private Grid grid;
        private Message message;
        private Label titleLabel;
        private Label detailsLabel;
        private Label dateLabel;
        private Label sizeLabel;
        private CheckBox checkBox;
        private TranslateTransform translation = new TranslateTransform { X = -55f };

        public EMailItem()
            : base()
        {
            CanPan = true;
            Margin = new Margin(0, 0, ScrollViewer.ScrollbarWidth, 10);
            titleLabel = new Label
            {
                Font = FontPool.MediumRegularFont,
                Margin = new Margin(5, 5, 5, 0),
                LineMode = LineMode.EndEllipsis,
                AutoSize = true
            };
            detailsLabel = new Label
            {
                Margin = new Margin(5, 0, 0, 0),
                Opacity = 200,
                LineMode = LineMode.WordWrap,
                AutoSize = false,
                LineAlignment = Alignment.Near,
                TextColor = PhoneColors.Accent
            };
            dateLabel = new Label
            {
                Margin = new Margin(null, 5, 5, null),
                FontScale = 0.75f,
                LineAlignment = Alignment.Near,
                Alignment = Alignment.Far,
                AutoSize = true
            };
            sizeLabel = new Label
            {
                Margin = new Margin(null, 2, 5, null),
                FontScale = 0.75f,
                LineAlignment = Alignment.Near,
                Alignment = Alignment.Far,
                AutoSize = true
            };

            checkBox = new CheckBox { Margin = new Margin { Top = 4, Left = 5 }, Size = new Size(48, 48), TextColor = PhoneColors.Dark };
            checkBox.CheckedChanged += new EventHandler(checkBox_CheckedChanged);

            grid = new Grid { Margin = new Margin(0, 0, infoWidth - 55, 0) };
            grid.Rows.AddRange(GridUnitType.Auto, 1f);
            grid.Columns.AddRange(55, 1f);
            grid.Transformation = translation;

            grid.SetControl(checkBox, 0, 0, 1, 1);
            grid.SetControl(titleLabel, 1, 0);
            grid.SetControl(detailsLabel, 1, 1);

            Grid dateSizeGrid = new Grid { Margin = new Margin(null, 0, 0, 0), Width = infoWidth, Background = PhoneColors.White };
            dateSizeGrid.Columns.AddRange(infoWidth);
            dateSizeGrid.Rows.AddRange(GridUnitType.Auto, GridUnitType.Auto, GridUnitType.Auto);

            dateSizeGrid.SetControl(dateLabel, 0, 0);
            dateSizeGrid.SetControl(sizeLabel, 0, 1);

            Panel panel = new Panel { Margin = Margin.Zero };

            panel.Controls.Add(grid, dateSizeGrid);
            AutoHeight = false;
            Height = 140;
            Chrome = new BorderShape { BorderSize = 1, Edges = BorderEdge.Bottom, Color = PhoneColors.Medium };
            this.Control = panel;
            Background = PhoneColors.White;
            TextColor = PhoneColors.Black;
        }

        void checkBox_CheckedChanged(object sender, EventArgs e)
        {
            IsChecked = checkBox.IsChecked;
        }


        public bool IsChecked
        {
            get { return checkBox.IsChecked; }
            set
            {
                if (message != null) message.IsChecked = value;
                checkBox.IsChecked = value;
            }
        }


        private static PropertyAccessor<EMailItem, float> OffsetProperty = new PropertyAccessor<EMailItem, float>("Offset",
            c => c.translation.X, (c, v) => { c.translation.X = v; c.Invalidate(InvalidationFlag.Transformation); });

        private bool isCheckBoxVisible;

        public bool IsCheckBoxVisible
        {
            get { return isCheckBoxVisible; }
            set
            {
                //if (isCheckBoxVisible != value)
                {
                    isCheckBoxVisible = value;
                    OnCheckboxVisibilityChanged();
                }
            }
        }

        private void OnCheckboxVisibilityChanged()
        {
            //translation.X = isCheckBoxVisible ? 0f : -55f;
            //Invalidate(InvalidationFlag.Transformation);
            FloatTransition t = new FloatTransition { Duration = 200, To = isCheckBoxVisible ? 0f : -55f };
            OffsetProperty.Animate(this, t);
            //CheckBoxWidthProperty.Animate(this, t);
        }

        protected override void OnDataChanged()
        {
            base.OnDataChanged();
            message = DataValue as Message;
            if (message != null)
            {
                bool read = message.ReadFlag;
                titleLabel.Font = read ? FontPool.MediumRegularFont : FontPool.MediumBoldFont;
                titleLabel.Text = message.Sender != null ? message.Sender : "{no sender}";
                StringBuilder sb = new StringBuilder();
                detailsLabel.Text = message.Subject;
                sizeLabel.Text = GetSize(message.Size);
                dateLabel.Text = GetDate(message);
                IsChecked = message.IsChecked;
            }
        }

        private string GetSize(int size)
        {
            if (size < 4095) return string.Format("{0} B", size);
            size /= 1024;
            if (size < 4095) return string.Format("{0} KB", size);
            size /= 1024;
            return string.Format("{0} MB", size);
        }

        /// <summary>
        /// When the checkbox is visible and a pan to the left is performed, notify the host to close all checkboxes
        /// by sending a command.
        /// </summary>
        protected override void OnBeginPan(PanEventArgs e)
        {
            if (e.Direction == PanDirection.Left && IsCheckBoxVisible)
            {
                e.Handled = true;
                e.Cancel = true;
                RaiseCommand(OutlookCommands.DisableEMailItemSelectMode);
            }
            base.OnBeginPan(e);
        }


        private string GetDate(Message message)
        {
            DateTime d = message.DeliveryDate;
            DateTime day = d.Date;
            if (day.Date.Equals(DateTime.Now.Date))
            {
                return d.ToShortTimeString();
            }
            else
            {
                int days = (DateTime.Now.Date - day).Days;
                if (days < 7)
                {
                    return CultureInfo.CurrentUICulture.DateTimeFormat.ShortestDayNames[(int)day.DayOfWeek];
                }
                return day.ToShortDateString();
            }
        }
    }
}
